package cn.com.cetccst.appstore.database.model;

import static cn.com.cetccst.appstore.database.model.AppModel.TABLE_NAME;
import static cn.com.cetccst.tools.pm.AppPackage.getVersionCode;
import static cn.com.cetccst.tools.pm.AppPackage.isPackageFound;
import static cn.com.cetccst.tools.pm.AppPackage.isWebApp;

import android.content.Context;
import android.content.res.Resources;

import androidx.annotation.NonNull;
import androidx.room.ColumnInfo;
import androidx.room.Embedded;
import androidx.room.Entity;
import androidx.room.Ignore;
import androidx.room.TypeConverters;

import com.google.gson.annotations.SerializedName;

import org.jetbrains.annotations.NotNull;

import java.util.ArrayList;
import java.util.List;

import cn.com.cetccst.appstore.R;
import cn.com.cetccst.appstore.database.converter.ListPlatformConverter;
import cn.com.cetccst.appstore.database.converter.StringArrayConverter;
import cn.com.cetccst.appstore.manager.ApkDownloadManager;

@Entity(tableName = TABLE_NAME, primaryKeys = {"id"})
@TypeConverters({StringArrayConverter.class, ListPlatformConverter.class})
public class AppModel {

    public static final String TABLE_NAME = "app_model";

    @ColumnInfo(name = "object")
    @SerializedName("object")
    private String object;

    @ColumnInfo(name = "id")
    @NonNull
    @SerializedName("id")
    private String appId;

    @ColumnInfo(name = "app_name")
    @SerializedName("app_name")
    private String appName;
    @Embedded
    @SerializedName("app_summary")
    private AppSummary appSummary = new AppSummary();
    @ColumnInfo(name = "app_type")
    @SerializedName("app_type")
    private String appType;
    @ColumnInfo(name = "big_icon_url")
    @SerializedName("big_icon_url")
    private String appBigIconUrl;
    @ColumnInfo(name = "create_time", defaultValue = "0")
    @SerializedName("create_time")
    private long createTime;
    @ColumnInfo(name = "category_id")
    @SerializedName("category_id")
    private String[] appCategoryId = new String[0];
    @ColumnInfo(name = "category_name", defaultValue = "")
    @SerializedName("category_name")
    private String[] appCategoryName = new String[0];
    @ColumnInfo(name = "force_install")
    @SerializedName("force_install")
    private boolean forceInstall;
    @ColumnInfo(name = "is_mondatory")
    @SerializedName("is_mondatory")
    private boolean isMondatory;
    @ColumnInfo(name = "original_app_id_string")
    @SerializedName("original_app_id_string")
    private String originalAppId;
    @ColumnInfo(name = "small_icon_url")
    @SerializedName("small_icon_url")
    private String appSmallIconUrl;
    @ColumnInfo(name = "update_time", defaultValue = "0")
    @SerializedName("update_time")
    private long updateTime;
    @ColumnInfo(name = "who_did_this")
    @SerializedName("who_did_this")
    private String whoDidThis;
    @ColumnInfo(name = "rating", defaultValue = "0")
    //100代表常用应用，0是普通应用
    @SerializedName("rating")
    private int rating;
    @ColumnInfo(name = "platform_details")
    @SerializedName("platform_details")
    private List<PlatformDetail> platformDetails;
    @ColumnInfo(name = "need_upgrade", defaultValue = "0")
    private boolean needUpgrade;//持久化为了动态驱动UI
    @ColumnInfo(name = "range", defaultValue = "0")
    private long range; //持久化为了动态驱动UI
    @ColumnInfo(name = "status", defaultValue = "0")
    private ApkStatus status = ApkStatus.STATUS_UNDOWNLOADED;//持久化为了动态驱动UI

    @Ignore
    @SerializedName("publisher_id")
    private String publisherId;
    @Ignore
    @SerializedName("description")
    private String description;

    public AppModel() {
        appId = "";
    }

    public String getObject() {
        return object;
    }

    public void setObject(String object) {
        this.object = object;
    }

    public String getAppId() {
        return appId;
    }

    public void setAppId(String appId) {
        this.appId = appId;
    }

    public String getAppName() {
        return appName;
    }

    public void setAppName(String appName) {
        this.appName = appName;
    }

    public AppSummary getAppSummary() {
        return appSummary;
    }

    public void setAppSummary(AppSummary appSummary) {
        this.appSummary = appSummary;
    }

    public String getAppType() {
        return appType;
    }

    public void setAppType(String appType) {
        this.appType = appType;
    }

    public String getAppBigIconUrl() {
        return appBigIconUrl;
    }

    public void setAppBigIconUrl(String appBigIconUrl) {
        this.appBigIconUrl = appBigIconUrl;
    }

    public long getCreateTime() {
        return createTime;
    }

    public void setCreateTime(long createTime) {
        this.createTime = createTime;
    }

    public String[] getAppCategoryId() {
        return appCategoryId;
    }

    public void setAppCategoryId(String[] appCategoryId) {
        this.appCategoryId = appCategoryId;
    }

    public String[] getAppCategoryName() {
        return appCategoryName;
    }

    public void setAppCategoryName(String[] appCategoryName) {
        this.appCategoryName = appCategoryName;
    }

    public String getCategoryName() {
        return appCategoryName == null || appCategoryName.length <= 0 ? Resources.getSystem().getResourceName(R.string.no_category) : appCategoryName[0];
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public boolean isForceInstall() {
        return forceInstall;
    }

    public void setForceInstall(boolean forceInstall) {
        this.forceInstall = forceInstall;
    }

    public boolean isMondatory() {
        return isMondatory;
    }

    public void setMondatory(boolean mondatory) {
        isMondatory = mondatory;
    }

    public String getOriginalAppId() {
        return originalAppId;
    }

    public void setOriginalAppId(String originalAppId) {
        this.originalAppId = originalAppId;
    }

    public String getPublisherId() {
        return publisherId;
    }

    public void setPublisherId(String publisherId) {
        this.publisherId = publisherId;
    }

    public String getAppSmallIconUrl() {
        return appSmallIconUrl;
    }

    public void setAppSmallIconUrl(String appSmallIconUrl) {
        this.appSmallIconUrl = appSmallIconUrl;
    }

    public long getUpdateTime() {
        return updateTime;
    }

    public void setUpdateTime(long updateTime) {
        this.updateTime = updateTime;
    }

    public String getWhoDidThis() {
        return whoDidThis;
    }

    public void setWhoDidThis(String whoDidThis) {
        this.whoDidThis = whoDidThis;
    }

    public int getRating() {
        return rating;
    }

    public void setRating(int rating) {
        this.rating = rating;
    }

    public ApkStatus getStatus() {
        return status;
    }

    public void setStatus(ApkStatus status) {
        this.status = status;
    }

    public long getRange() {
        return range;
    }

    public void setRange(long range) {
        this.range = range;
    }

    public boolean isNeedUpgrade() {
        return needUpgrade;
    }

    public void setNeedUpgrade(boolean needUpgrade) {
        this.needUpgrade = needUpgrade;
    }

    public List<PlatformDetail> getPlatformDetails() {
        return platformDetails;
    }

    public void setPlatformDetails(List<PlatformDetail> platformDetails) {
        this.platformDetails = platformDetails;
    }

    public void detectAppStatus(Context context) {
        setStatus(ApkStatus.STATUS_UNDOWNLOADED);
        String pkgName = getAppSummary().getAppPackageName();
        if(isWebApp(pkgName)){
            setStatus(ApkStatus.STATUS_INSTALLED);
        } else {
            boolean isPackageFound = isPackageFound(context, pkgName);
            if (isPackageFound) {
                int localVersionCode = getVersionCode(context, getAppSummary().getAppPackageName());
                setNeedUpgrade(getAppSummary().getAppVersionCode() > localVersionCode);
                setStatus(ApkStatus.STATUS_INSTALLED);
            } else {
                ApkDownloadManager.getInstance().detectDownloadStatus(context, this);
            }
        }
    }

    public List<String> getScreenshots() {
        List<String> list = new ArrayList<>();
        if (platformDetails != null) {
            for (PlatformDetail platformDetail : platformDetails) {
                if (platformDetail.getScreenshots() != null) {
                    for (Screenshot screenshot : platformDetail.getScreenshots()) {
                        list.add(screenshot.getScreenshotUrl());
                    }
                }
            }
        }
        return list;
    }

    /**
     * 根据app状态获取按钮应该显示的名称
     */
    public int getResIdByStatus() {
        if (status == null) {
            return R.string.store_install;
        }
        switch (status) {
            case STATUS_INSTALLED -> {
                if (needUpgrade)
                    return R.string.store_upgrade;
                return R.string.store_open;
            }
            case STATUS_DOWNLOADED -> {
                return R.string.store_install;
            }
            default -> {
                return R.string.store_download;
            }
        }
    }

    public static class PlatformDetail {

        @SerializedName("platform")
        private String platform;
        @SerializedName("screenshots")
        private List<Screenshot> screenshots;

        public String getPlatform() {
            return platform;
        }

        public void setPlatform(String platform) {
            this.platform = platform;
        }

        public List<Screenshot> getScreenshots() {
            return screenshots;
        }

        public void setScreenshots(List<Screenshot> screenshots) {
            this.screenshots = screenshots;
        }
    }

    public static class Screenshot {
        @SerializedName("screenshot_url")
        private String screenshotUrl;

        public String getScreenshotUrl() {
            return screenshotUrl;
        }

        public void setScreenshotUrl(String screenshotUrl) {
            this.screenshotUrl = screenshotUrl;
        }
    }

    public enum ApkStatus {

        STATUS_UNDOWNLOADED(0),
        STATUS_INSTALLED(1),
        STATUS_DOWNLOADING(2),
        STATUS_DOWNLOADED(3);

        private int value;

        private ApkStatus(int value) {
            this.value = value;
        }

        public int value() {
            return this.value;
        }

        public static ApkStatus valueOf(int value) {
            switch (value) {
                case 0:
                    return STATUS_UNDOWNLOADED;
                case 1:
                    return STATUS_INSTALLED;
                case 2:
                    return STATUS_DOWNLOADING;
                case 3:
                    return STATUS_DOWNLOADED;
                default:
                    return null;
            }
        }

    }

    @Override
    public boolean equals(Object obj) {
        if (obj != null && obj instanceof AppModel) {
            AppModel appModel = (AppModel) obj;
            if (this.getAppId().equals(appModel.getAppId())) {
                return true;
            }
        }
        return false;
    }

}
